Kelsey Shi

返回

第二章学习笔记-swift语法

#dev# #study#
发布于 2024-04-22

100 小时后请叫我苹果开发者

运算符、条件判断及类型

运算符

条件判断

if else:

if condition {
} else if condition1 {
} else {
}

区间: 1…7 2..<9

switch:

switch{
case 1:
}

类型 Types

用函数将代码归类为功能

func driveTowards(direction: Srting, meters: Int){}
driveTowards(directions: "", meters: 100)

若希望省略参数标签,可使用 swift 语言的省略符号 _

func driveTowards(_ direction: String, for meters: Int){}
driveTowards("", for: 100)
func driveTowards(_ direction: String = "", for meters: Int){}
driveTowaords(for: 100)
func rollDice() -> Int {
Int.random(in: 1...6)
}

用集合与循环处理数据

集合类型数组 Array

var weightRecordsA = [70.4, 70.3, 70.1]
var weightRecordsB: [Double] = []

常见方法

var arr = [70.4, 70.3, 70.1]
// 添加
arr.append(80.2)
arr += [89.1, 33.3]
arr.insert(70.2, at: 3)
// 删除
arr.remove(at: 2)
arr.removeSubrange(3...7)
arr.removeAll()
// 使用
arr[1]
arr.randomElement()
arr.firstIndex(of: 70.2)
// 原位修改
arr[0] = 89.2
arr.sort()
arr.shuffle()
// 新数组修改
newArr = arr.map { ($0 - targetWeight) }
newArr = arr.filter { $0 - 79.2 }
// 判断数组当前状态
arr.count
arr.isEmpty
arr.min()
arr.contains(77.2)

集合类型字典 Dictionary

let PhoneBookA: [String: Int] = [:]
let PhoneBookB= ["老王":12345]

循环

编程范型,闭包及可选类型

闭包

// 函数
func isTheFirstSmallerThanSecond(first: Int, second: Int) -> Bool {
return first < second
}
// 闭包
let closure = { (first: Int, second: Int) -> Bool in
return first < second
}
// by: 使用
numberArr.sort(by: closure)
numberArr.sort(by: { (first: Int, second: Int) -> Bool in
return first < second
})
numberArr.sort { (first: Int, second: Int) -> Bool in
return fisrt < second
}
numbersArr.sort { (first, second) in
return first < second

进一步省略参数位置的括号、函数功能代码仅存在一行返回值时,关键词 return 可省略

numbers.sort { first, second in first < second }
numberArr.sort { $0 < $1 }

可选类型 Optional

// num可以存储 数字/空 两个状态
let num: Int? = 1
var username: String? = "小王"
print(username!)
if username != b {
let safelyUnwrappedUsername = username!
print("\(safelyUnwrappedUsername),想听点什么")
}
if let safelyUnwrappedUsername = username {
print("\(safelyUnwrappedUsername),想听点什么")
}
func guardDemo() {
guard let safelyUnwrappedUsername = username else{
print("username = nil")
return
}
print("\(safelyUnwrappedUsername),想听点什么")
}
var username = nil;
print("\(username ?? "你好"), 想听点什么?")

用「结构」创建自定义类型

struct Player {
static var allPlayers: [Player] = []
var name: String
var livesRemaining = 5 {
willSet {
print("警告 还剩下\(newValue) 条命")
}
didSet {
if livesRemaining != 0 {
print("已满血复活")
} else {
print("游戏结束")
}
}
}
let maxHealth = 100
lazy var currentHealth = maxHealth
var isPlayerOutOfLives: Bool {
get {
livesRemaining == 0 ? true : false
}
set {
if newValue {
livesRemaining = 0
}
}
}
init(name: String) {
self.name = name ;
}
init(name: String, livesRemaining: Int, currentHealth: Int){
self.name = name
self.livesRemaining = livesRemaining
self.currentHealth = currentHealth
}
mutating func damaged(by health: Int){}
static func recentAddedPlayer() -> Player {
allPlayers[allPlayers.count - 1]
}
}
let player = Player(name: "player")
player.name
let maxHealth = 100
lazy var currentHealth = maxHealth
var a = 4 {
willSet {
newValue
}
didSet {
oldValue
}
}
var b: Bool {
get {
// 设定b的值
}
set {
// 修改其他属性的值
newValue
}
}
struct Player{
static var allPlayers: [Player] = []
static func recentAddedPlayer() -> Player {
allPlayers[allPlayers.count - 1]
}
}
var wang = Player(name:"wang")
Player.allPlayers.append(contentsOf: [wang])
Player.recentAddedPlayer().name

将信息归类

enum Source{
case num1
case num2
}
var a =Source.num1
switch a{
case .num1:
}

与 struc 区别:class 与 struct 在内存中的存储方式不同;class 支持创建更复杂的父子关系,而 struct 不支持;class 必须写明初始化器,而 struct 自带默认的初始化器。

覆盖 override ;继承父类 super;

class 子类实体在同一个数组中转化为父类,以满足数组仅能存储同一类型数值的要求。判断数组中是否存在子类型的关键词是is。判断并改变类型的语法是as? (符合特征,则创类型变量)

for car in cars {
if car is Truck {}
if let teslaModel3 = car as? Sedan{}
}
extension Car {
var quckInfo: String {
"The car brand is \(brand)"
}
}

用协议建立规则

别名 typealias

typealias PhoneBook = [String: Int]
typealias Age = Int

用协议建立规则

协议 Protocol 表明做法,但不具体提供做什么,类似后端的 Service 和 ServiceImpl 里的 Service,支持 struct、class、enum

// 描述性的protocol
protocol Expressible {
var name: String { get }
init(name: String)
}
// 以下两种使用写法效果一致
struct User: Expressible{
var name: String
}
extension User: Expressible {}

属性 Property:需统一使用关键词 var ,只读可改都需标明 { get set }

常见的协议类型

Equatable (可等性)、Comparable (可比性)、Hashable (可哈希性)、Identifiable (可辨识性)、Codable (可编码性)

在自定义类中可比较,因为 == 不支持比较自定义类型。 若自定义类型中仅包含基础类型,则可以省略类方法 static func == (Self, Self) -> Bool 的写法

struct Todo: Equatable {
var content: String;
// ignore
static func ==(lhs:Todo,rhs:Todo)->Bool{
return lhs.content == rhs.content
}
}
extesnion Todo: Comparable {
static func < (lhs: Todo, rhs: Todo) -> Bool {}
}

Hash 是将现有的数据结构通过一定预算转化为一个随机的、不可重复的、独特的值,

struct day: Hashable{}
let todoOne = day()
let todoTwo = day()
// 对于字典的key来说,其数值应该是唯一的。
let todos = [dayOne:todoOne,dayTwo:todoTwo]

可辨识性协议要求我们添加一个名为 id 的属性,该属性必须包含一个可哈希的数值,名为 id。

strcut Todo: Equatable, Identifiable {
var content: String;
var id = UUID()
}

异常处理及 App 的生命周期

enum PasswordError: Error {
case notLongEnough
}
func validatePassword(_ password: String) throws -> Bool {
if password.count < 6{
throw PasswordError.notLongEnough
}
return true;
}
var password = "1234"
do{
try validatePassword(password)
print("pass")
} catch passwordError.notLongEnough {
print("at least 6")
}
if let validated = try? validatePassword(password) {
print("passed")
} else {
print("at least 6")
}
// try! 运行函数,但彻底忽略错误
try! validatePassword(password)

生命周期

Task Async Await

var body: some View{
Text("Concurrency")
.task {
await truck()
}
}
func truck() async {
// 一些繁琐任务
for i in 0...<1_000_000_000{
print(i)
}
}
最后编辑于 Invalid DateTime